package com.ds.robot.assistant.service.impl;

import cn.hutool.core.lang.Dict;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.cache.LoadingCache;
import com.ds.robot.assistant.dao.BugInfoMapper;
import com.ds.robot.assistant.dto.BugConditionDTO;
import com.ds.robot.assistant.entity.BugInfo;
import com.ds.robot.assistant.service.BugInfoService;
import com.ds.robot.assistant.vo.BugVO;
import com.ds.robot.assistant.vo.TesterBugVO;
import com.ds.robot.assistant.vo.resp.ChartData;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 15910
 * @description 针对表【bug_info(缺陷信息表)】的数据库操作Service实现
 * @createDate 2024-11-06 09:55:28
 */
@Service
@Slf4j
public class BugInfoServiceImpl extends ServiceImpl<BugInfoMapper, BugInfo>
        implements BugInfoService {

    @Resource
    private LoadingCache<String, String> userCache;

    private static final int MAX_DAY_SIZE = 40;

    // @Value("${tester.account}")
    @Value("#{'${tester.account}'.split(',')}")
    private List<String> testerAccountList;


    @Override
    public List<BugVO> selectBugInfoByCondition(BugConditionDTO condition) {
        log.info("查询Bug列表，查询条件={}", JSON.toJSONString(condition));
        List<BugVO> voList = this.baseMapper.selectBugVOList(condition.getAccountId(), condition.getStartTime(), condition.getEndTime());
        if (voList != null && !voList.isEmpty()) {
            for (BugVO vo : voList) {
                vo.setOtherCount(vo.getTotalCount() - vo.getConfirmCount() - vo.getReopenCount() - vo.getProcessingCount() - vo.getFixedCount()
                        - vo.getClosedCount() - vo.getCanceledCount() - vo.getInvalidCount());
                vo.setEffectiveCount(vo.getTotalCount() - vo.getCanceledCount() - vo.getInvalidCount());

                if (!StringUtils.hasText(vo.getAccountName())) {
                    String accountName = userCache.getIfPresent(vo.getAccountId());
                    if (StringUtils.hasText(accountName)) {
                        log.info("通过缓存设置缺陷负责人姓名={}, 用户ID={}", accountName, vo.getAccountId());
                        vo.setAccountName(accountName);
                    } else {
                        vo.setAccountName(vo.getAccountId());
                    }
                }
            }
            voList.sort(Comparator.comparing(BugVO::getEffectiveCount).reversed());
            return voList;
        }
        return Collections.emptyList();
    }

    @Override
    public List<ChartData> selectChartDataByCondition(BugConditionDTO condition) {
        // 先按天查询这个人的Bug天数
        List<Map<String, Object>> mapList = this.baseMapper.selectBugDayCountByCondition(condition);
        List<ChartData> chartDataList;
        int size = mapList.size();
        if (size < MAX_DAY_SIZE) {
            log.info("查询天数={}， 按天汇总", size);
            chartDataList = baseMapper.selectBugCountByDay(condition);
        } else {
            // 按照周查询汇总这个人的Bug数量
            log.info("查询天数={}， 按周汇总", size);
            chartDataList = baseMapper.selectBugCountByWeek(condition);
            chartDataList.forEach(chartData -> {
                chartData.setDate(chartData.getDate().substring(0, 4) + "年" + chartData.getDate().substring(4) + "周");
            });
        }
        return chartDataList;
    }

    @Override
    public Dict selectLineChartDataByCondition(BugConditionDTO condition) {
        // 先按天查询这个人的Bug天数
        List<Map<String, Object>> mapList = this.baseMapper.selectBugDayCountByCondition(condition);
        List<ChartData> chartDataList;
        List<ChartData> closeChartDataList;
        int size = mapList == null ? 0 : mapList.size();
        if (size < MAX_DAY_SIZE) {
            log.info("折线图查询天数={}， 按天汇总", size);
            chartDataList = baseMapper.selectBugCountByDay(condition);
            closeChartDataList = baseMapper.selectCloseBugCountByDay(condition);
        } else {
            // 按照周查询汇总这个人的Bug数量
            log.info("折线图查询天数={}， 按周汇总", size);
            chartDataList = baseMapper.selectBugCountByWeek(condition);
            closeChartDataList = baseMapper.selectCloseBugCountByWeek(condition);
            processWeek(chartDataList, closeChartDataList);
        }
        List<String> xAxisList = getXAxisList(chartDataList, closeChartDataList);
        return Dict.create().set("xAxis", xAxisList).set("create", chartDataList).set("closed", closeChartDataList);
    }

    @Override
    public List<TesterBugVO> selectTesterBugByCondition(BugConditionDTO condition) {
        log.info("查询测试Bug列表，查询条件={}", JSON.toJSONString(condition));
        log.info("测试人员列表={}", testerAccountList);
        List<TesterBugVO> voList = this.baseMapper.selectTesterBugVOList(testerAccountList, condition.getStartTime(), condition.getEndTime());
        if (voList != null && !voList.isEmpty()) {
            for (TesterBugVO vo : voList) {
                vo.setOtherCount(vo.getTotalCount() - vo.getFixedCount() - vo.getClosedCount() - vo.getCanceledCount() - vo.getInvalidCount());
                vo.setEffectiveCount(vo.getTotalCount() - vo.getCanceledCount() - vo.getInvalidCount());

                if (!StringUtils.hasText(vo.getAccountName())) {
                    String accountName = userCache.getIfPresent(vo.getAccountId());
                    if (StringUtils.hasText(accountName)) {
                        log.info("通过缓存设置测试姓名={}, 用户ID={}", accountName, vo.getAccountId());
                        vo.setAccountName(accountName);
                    } else {
                        vo.setAccountName(vo.getAccountId());
                    }
                }
            }
            voList.sort(Comparator.comparing(TesterBugVO::getEffectiveCount).reversed());
            return voList;
        }
        return Collections.emptyList();
    }

    @Override
    public Dict selectTesterLineChartDataByCondition(BugConditionDTO condition) {
        // 先按天查询这个人的Bug天数
        List<Map<String, Object>> mapList = this.baseMapper.selectTesterBugDayCountByCondition(testerAccountList, condition.getStartTime(), condition.getEndTime());
        List<ChartData> chartDataList;
        List<ChartData> closeChartDataList;
        int size = mapList == null ? 0 : mapList.size();
        if (size < MAX_DAY_SIZE) {
            log.info("测试人员折线图查询天数={}， 按天汇总", size);
            chartDataList = baseMapper.selectTesterBugCountByDay(condition);
            closeChartDataList = baseMapper.selectTesterCloseBugCountByDay(condition);
        } else {
            // 按照周查询汇总这个人的Bug数量
            log.info("测试人员折线图查询天数={}， 按周汇总", size);
            chartDataList = baseMapper.selectTesterBugCountByWeek(condition);
            closeChartDataList = baseMapper.selectTesterCloseBugCountByWeek(condition);
            processWeek(chartDataList, closeChartDataList);
        }
        List<String> xList = getXAxisList(chartDataList, closeChartDataList);
        return Dict.create().set("xAxis", xList).set("create", chartDataList).set("closed", closeChartDataList);
    }


    private static @NotNull List<String> getXAxisList(List<ChartData> chartDataList, List<ChartData> closeChartDataList) {
        Set<String> xAxisSet = chartDataList.stream().map(ChartData::getDate).collect(Collectors.toSet());
        xAxisSet.addAll(closeChartDataList.stream().map(ChartData::getDate).collect(Collectors.toSet()));
        // 按照date排序
        return xAxisSet.stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList());
    }

    private void processWeek(List<ChartData> chartDataList, List<ChartData> closeChartDataList) {
        chartDataList.forEach(chartData -> {
            chartData.setDate(chartData.getDate().substring(0, 4) + "年" + chartData.getDate().substring(4) + "周");
        });
        closeChartDataList.forEach(closeChartData -> {
            closeChartData.setDate(closeChartData.getDate().substring(0, 4) + "年" + closeChartData.getDate().substring(4) + "周");
        });
    }

}


